package com.example.xpvideo.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.xpvideo.entity.LsGoodsCategory;
import com.example.xpvideo.entity.ResponseResult;
import com.example.xpvideo.enums.ErrCodeEnum;
import com.example.xpvideo.mapper.LsGoodsCategoryMapper;
import com.example.xpvideo.service.FileService;
import com.example.xpvideo.service.LsGoodsCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 平台商品分类(LsGoodsCategory)Service层
 *
 * @author 杨丽辉
 * @since 2021-08-16 11:07:03
 */
@Service
@Transactional(rollbackFor = {RuntimeException.class, Exception.class})
public class LsGoodsCategoryServiceImpl implements LsGoodsCategoryService {
    @Autowired
    private LsGoodsCategoryMapper lsGoodsCategoryMapper;
    @Autowired
    private FileService fileService;

    public static String IMG_TYPE_ICON = "ICON";


    /**
     * 通过ID和其他条件查询单条数据
     *
     * @param lsGoodsCategory 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public LsGoodsCategory queryLsGoodsCategoryLimit1(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.queryLsGoodsCategoryLimit1(lsGoodsCategory);
    }

    /**
     * 查询指定行数据
     *
     * @param lsGoodsCategory 实例对象
     * @param offset          查询起始位置
     * @param limit           查询条数
     * @return 对象列表
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public List<LsGoodsCategory> queryAllLsGoodsCategoryByLimit(LsGoodsCategory lsGoodsCategory, Integer offset, Integer limit) {
        return lsGoodsCategoryMapper.queryAllLsGoodsCategoryByLimit(lsGoodsCategory, offset, limit);
    }

    /**
     * 查询数据条数
     *
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int countAllLsGoodsCategory(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.countAllLsGoodsCategory(lsGoodsCategory);
    }

    /**
     * 通过实体作为筛选条件查询
     *
     * @param lsGoodsCategory 实例对象
     * @return 对象列表
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public List<LsGoodsCategory> queryAllLsGoodsCategory(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.queryAllLsGoodsCategory(lsGoodsCategory);
    }

    /**
     * 新增数据
     *
     * @param lsGoodsCategory 实例对象
     * @return 影响行数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int insertLsGoodsCategory(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.insertLsGoodsCategory(lsGoodsCategory);
    }

    /**
     * 修改数据
     *
     * @param lsGoodsCategory 实例对象
     * @return 影响行数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int updateLsGoodsCategory(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.updateLsGoodsCategory(lsGoodsCategory);
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 影响行数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int deleteLsGoodsCategoryById(Integer id) {
        return lsGoodsCategoryMapper.deleteLsGoodsCategoryById(id);
    }

    /**
     * 通过主键列表删除，列表长度不能为0
     *
     * @param list 集合
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int deleteLsGoodsCategoryByIds(List<Integer> list) {
        return lsGoodsCategoryMapper.deleteLsGoodsCategoryByIds(list);
    }

    /**
     * 通过主键修改实体列表，列表长度不能为0，注意：当实体属性为null时，对应的列也会别更新为null
     *
     * @param list 集合
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int updateLsGoodsCategoryBatch(List<LsGoodsCategory> list) {
        return lsGoodsCategoryMapper.updateLsGoodsCategoryBatch(list);
    }

    /**
     * 批量其他列,除主键以外的列，列表长度不能为0,字段是空的就置为null
     *
     * @param list 集合
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int insertLsGoodsCategoryBatch(List<LsGoodsCategory> list) {
        return lsGoodsCategoryMapper.insertLsGoodsCategoryBatch(list);
    }

    /**
     * 通过实体非空属性删除
     *
     * @param lsGoodsCategory 实体
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int deleteLsGoodsCategoryByEntity(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.deleteLsGoodsCategoryByEntity(lsGoodsCategory);
    }

    /**
     * 通过实体不为空的属性作为筛选条件查询列表
     *
     * @param lsGoodsCategory 实体
     * @return list
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public List<LsGoodsCategory> listLsGoodsCategoryByEntity(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.listLsGoodsCategoryByEntity(lsGoodsCategory);
    }

    /**
     * 新增实体属性不为null的列
     *
     * @param lsGoodsCategory 实体
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int insertLsGoodsCategorySelect(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.insertLsGoodsCategorySelect(lsGoodsCategory);

    }

    /**
     * 批量新增新增实体属性不为null的列
     *
     * @param list 实体
     * @return 条数
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public int insertLsGoodsCategoryListSelect(List<LsGoodsCategory> list) {

        return lsGoodsCategoryMapper.insertLsGoodsCategoryListSelect(list);
    }

    /**
     * 通过实体不为空的属性作为筛选条件查询单个
     *
     * @param lsGoodsCategory 实体
     * @return 单个
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public LsGoodsCategory getLsGoodsCategoryByEntity(LsGoodsCategory lsGoodsCategory) {
        return lsGoodsCategoryMapper.getLsGoodsCategoryByEntity(lsGoodsCategory);
    }


    /**
     * 查出所有分类以及子分类，以树形结构组装起来
     *
     * @return ResponseResult 结果
     */
    public ResponseResult queryCategory() {
        // 1. 查出所有分类
        List<LsGoodsCategory> entities = lsGoodsCategoryMapper.queryAllLsGoodsCategory(null);
        // 2. 组装成父子的树形结构
        // 2.1 找到所有的一级分类
        List<LsGoodsCategory> level1Menus = entities.stream().filter(categoryEntity ->
                        categoryEntity.getPid() == 0
                ).map(menu -> {
                    // 2.2 设置子菜单
                    menu.setChildren(getChildren(menu, entities));
                    return menu;
                    // 2.3 排序
                }).sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());
        return ResponseResult.responseResult(0, level1Menus);
    }

    /**
     * 递归查找所有菜单的子菜单
     */
    private List<LsGoodsCategory> getChildren(LsGoodsCategory root, List<LsGoodsCategory> all) {
        List<LsGoodsCategory> children = all.stream().filter(categoryEntity ->
                categoryEntity.getPid() == root.getId()
        ).map(categoryEntity -> {
            // 1. 找到子菜单
            categoryEntity.setChildren(getChildren(categoryEntity, all));
            return categoryEntity;
        }).sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))).collect(Collectors.toList());
        return children;
    }

    /**
     * 添加分类
     * @param goodsCategory 分类信息
     * @param file          icon 图片
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class,Exception.class})
    public ResponseResult insertCategory(LsGoodsCategory goodsCategory, MultipartFile file) {
        try {
            if (null!=file) {
                // 获取文件后缀
                String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
                if (!suffix.toUpperCase().equals(IMG_TYPE_ICON)) {
                    return ResponseResult.responseResult(500, "请选择.icon图片");
                }
                String url = fileService.addImages(file);
                goodsCategory.setImage(url);
            }
            // 创建于更新时间
            goodsCategory.setCreateTime(LocalDateTime.now());
            goodsCategory.setUpdateTime(goodsCategory.getCreateTime());
            // 计算分类等级
            if (goodsCategory.getPid() != 0) {
                // 查询上级等级+1
                LsGoodsCategory one = lsGoodsCategoryMapper.selectOne(new QueryWrapper<LsGoodsCategory>().eq("id", goodsCategory.getPid()).select("level"));
                goodsCategory.setLevel((Integer)one.getLevel()+1);
            } else {
                goodsCategory.setLevel(1);
            }
            // 添加三级分类必传icon图片
            if ((Integer)goodsCategory.getLevel() == 3 && goodsCategory.getImage()==null) {
                return ResponseResult.responseResult(500,"三级分类请上传.icon图标");
            }
            int i = lsGoodsCategoryMapper.insertLsGoodsCategorySelect(goodsCategory);
            if (i > 0) {
                return ResponseResult.responseResult(0,"添加成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.responseResult(ErrCodeEnum.unknown_20002, e.getMessage());
        }
        return ResponseResult.responseResult(ErrCodeEnum.unknown_20002, null);
    }


}

